package com.ce.framework.datamaintain.action;

import com.ce.framework.constants.WebConstants;
import com.ce.framework.datamaintain.dao.po.AbstractPO;
import com.ce.framework.datamaintain.logic.ISearchCondition;
import com.ce.framework.exception.AppException;
import com.ce.framework.util.BeanAccessUtil;
import com.ce.framework.util.GeneratorUUID;
import com.ce.framework.util.LogUtil;
import com.ce.framework.util.StringUtil;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 * 嫦娥软件有限公司 版权所有 2013
 * 创建人： andy
 * 创建时间： Aug 19, 2010 10:38:34 AM
 * 功能描述： ACTION操作基类,实现了单表，多表的增删改查
 *         功能，系统的每个ACTION都必须继承该基类
 * ==================================
 * 修改历史
 * 修改人        修改时间      修改位置（函数名）
 *
 * ==================================
 */
public abstract class DataMaintainAction extends SearchAction{


	private static final long serialVersionUID = 1L;

	/**
	 * 基本po类接口
	 */
	protected AbstractPO po;

	/**
     * op:请求的参数(扩展父类中的参数含义)
     * "open"	打开添加或修改页面
     * "save"	正常保存操作
     * "savejs"	采用AJAX保存
     * "look"	查看单条信息
     * "deljs"	采用AJAX删除记录
     */
	@Override
	public String execute() throws Exception {
	    
		if("look".equals(op)){//查看单条信息
			return this.look();
		}
		else {
			return super.execute();
		}
	}


	
	/**
	 * 开发人： andy
	 * 开发时间： Aug 24, 2010 9:40:12 AM
	 * 功能描述：通过组合SQL语句形成子表表查询条件，如果不是主子表操作时，该方法应当返回空
	 * 方法的参数和返回值
	 * @return
	 * @throws AppException
	 * ISearchCondition 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected ISearchCondition creatChildPoCondition()throws AppException{
		return null;
	}
	
	/**
	 * 开发人： andy
	 * 开发时间： Aug 24, 2010 9:41:33 AM
	 * 功能描述： 得到添加的子表数据
	 * 方法的参数和返回值
	 * @return
	 * @throws AppException
	 * List 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected List<?> getAddList()throws AppException{
		return null;
	}
	
	/**
	 * 开发人： andy
	 * 开发时间： Aug 24, 2010 9:41:36 AM
	 * 功能描述：得到修改的字表数据
	 * 方法的参数和返回值
	 * @return
	 * @throws AppException
	 * List 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected List<?> getModifyList()throws AppException{
		return null;
	}

	/**
	 * 开发人： andy
	 * 开发时间： 2012-11-07 10:08
	 * 功能描述：得到删除的字表数据
	 * 方法的参数和返回值
	 * @return
	 * @throws AppException
	 * List 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected List<?> getDeleteList() {
		return null;
	}

	public String add()throws AppException
	{
		if("save".equals(op)){
			return addItem();
		}
		else if("savejs".equals(op)){
			return addItemForJS();
		}
		else{
			return openAddPage();
		}
	}
	
	/**
	 * 开发人： andy
	 * 开发时间： Jul 7, 2010 2:58:36 PM
	 * 功能描述：打开数据添加界面
	 * 方法的参数和返回值
	 * @return
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected String openAddPage()throws AppException{
		this.initOtherData(true);
		if(this.m)
			return WebConstants.REQUEST_OPENADDPAGE_OPERATOR_MOBILE;
		return WebConstants.REQUEST_OPENADDPAGE_OPERATOR;
	}
	
	/**
	 * 开发人： andy
	 * 开发时间： Jul 7, 2010 3:13:00 PM
	 * 功能描述：添加数据
	 * 方法的参数和返回值
	 * @return
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected String addItem() throws AppException {
		if(this.validateSubmit()){
			this.initVcId();
			this.baselogic.addPo(po,this.getAddList());
			return this.list();			
		}else{
			throw new AppException("提交数据验证失败，操作未成功！");
		}

	}
	
	/**
	 * 开发人： andy
	 * 开发时间： 2013-9-9 下午07:24:14
	 * 功能描述：用于js框架的数据添加操作
	 * 方法的参数和返回值
	 * @return
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected String addItemForJS(){
		// TODO Auto-generated method stub
		try {
				if(this.validateSubmit())
				{
				   this.addItem();
				}
				else
				{
					return this.returnInfoForJS(false, "提交数据验证失败，操作未成功！");
				}
			} catch (Exception e)
				{
					LogUtil.logError(e);
					return this.returnInfoForJS(false, e.getMessage().replaceAll("'|\\n", " "));
				}
		return this.returnInfoForJS(true, null);
	}
	
	public String modify()throws AppException{
		if("save".equals(op)){
			return modifyItem();
		}
		else if("savejs".equals(op)){
			return modifyItemForJS();
		}
		else{
			return openModifyPage();
		}
	}
	
	/**
	 * 开发人： andy
	 * 开发时间： Jul 7, 2010 3:15:02 PM
	 * 功能描述：打开数据修改界面
	 * 方法的参数和返回值
	 * @return
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	@SuppressWarnings("deprecation")
	protected String openModifyPage()throws AppException{
		String selectId = this.getSelectId();
		if(StringUtil.isBlank(selectId))
			throw new AppException("没有选择要修改的记录");
		getRequest().getSession().setAttribute("LAST_MODIFY_ID", selectId);
		po = (AbstractPO) this.baselogic.getPOByPk(po.getClass().getName(), selectId);
		this.getNoDivedeSearchResult(this.creatChildPoCondition());//获取子表List数据
		this.initOtherData(false);
		if(this.m)
			return WebConstants.REQUEST_OPENMODIFYPAGE_OPERATOR_MOBILE;
		return WebConstants.REQUEST_OPENMODIFYPAGE_OPERATOR;
	}
	
	/**
	 * 开发人： andy
	 * 开发时间： Jul 7, 2010 3:15:13 PM
	 * 功能描述：更新数据
	 * 方法的参数和返回值
	 * @return
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected String modifyItem()throws AppException{
		if(this.validateSubmit()){
		    this.baselogic.updatePo(po,this.getAddList(),this.getModifyList(),this.getDeleteList());
			return this.searchData();			
		}else{
			throw new AppException("提交数据验证失败，操作未成功！");
		}

	}
	
	/**
	 * 开发人： andy
	 * 开发时间： 2013-9-9 下午07:12:28
	 * 功能描述：
	 * 方法的参数和返回值
	 * @return 用于js框架的数据更新操作
	 * @throws AppException
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected String modifyItemForJS(){
		// TODO Auto-generated method stub
		try {
			if(this.validateSubmit()){
			    this.modifyItem();
			}else{
				return this.returnInfoForJS(false, "提交数据验证失败，操作未成功！");
			}
		} catch (AppException e) {
			e.printStackTrace();
			return this.returnInfoForJS(false, e.getMessage());
		}
		return this.returnInfoForJS(true, null);
	}

	/**
	 * 开发人： andy
	 * 开发时间： Jul 8, 2010 11:34:59 AM
	 * 功能描述： 打开查看页面
	 * 方法的参数和返回值
	 * @return  
	 * @throws AppException
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected String look()throws AppException{
		String selectId = this.getSelectId();
		if(StringUtil.isBlank(selectId))
			throw new AppException("没有选择要修改的记录");
		po = (AbstractPO) this.baselogic.getPOByPk(po.getClass().getName(), selectId);
		this.getNoDivedeSearchResult(this.creatChildPoCondition());//获取子表List数据
		if(this.m)
			return WebConstants.REQUEST_LOOKDATA_OPERATOR_MOBILE;
		return WebConstants.REQUEST_LOOKDATA_OPERATOR;
	}

	/**
	 * 开发人： andy
	 * 开发时间： Jul 7, 2010 3:15:23 PM
	 * 功能描述：删除数据(包含子表删除)
	 * 方法的参数和返回值
	 * @return
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	public String del()throws AppException{
		if("deljs".equals(op)){
			return this.delItemForJS();
		}
		else{
			return this.delItem();
		}
	}
	/**
	 * 开发人： andy
	 * 开发时间： Jul 7, 2010 3:15:23 PM
	 * 功能描述：删除数据(包含子表删除)
	 * 方法的参数和返回值
	 * @return
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected String delItem()throws AppException{
		String[] delIds = this.getParameterValues(WebConstants.SELECT_ITEMS_NAMES);
		if(delIds==null||delIds.length==0){
			throw new AppException("没有选择要删除的记录");
		}
		String childPoName = null;
		this.getParameter(WebConstants.CHILD_PO_NAME);
		if(this.getParameter(WebConstants.CHILD_PO_NAME)!=null)
			childPoName = this.getParameter(WebConstants.CHILD_PO_NAME);
		this.baselogic.deleteLogic(po, delIds, WebConstants.DEFAULT_DELETE_FIELD,childPoName);//逻辑删除数据
		return this.searchData();
	}
	
	/**
	 * 开发人： andy
	 * 开发时间： 2013-9-9 下午07:24:57
	 * 功能描述：用于js框架的数据删除操作
	 * 方法的参数和返回值
	 * @return
	 * String 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	protected String delItemForJS(){
		// TODO Auto-generated method stub
		try {
			this.delItem();
		} catch (AppException e) {
			LogUtil.logError(e);
			return this.returnInfoForJS(false, e.getMessage().replaceAll("'|\\n", " "));
		}
		return this.returnInfoForJS(true, null);
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-18  下午06:19:45
	* 功能描述: 获取修改或查看页面中的记录ID
	* 方法的参数和返回值: 
	* @return
	*/
	protected String getSelectId(){
		String selectId = this.getParameter(WebConstants.SELECT_ITEMS_NAME);
		if(StringUtil.isBlank(selectId))
			selectId = (String)getAttribute(WebConstants.SELECT_ITEMS_NAME);
		return selectId;
	}

	/**
	* 开发人：andy
	* 开发日期: 2013-10-20  下午01:51:31
	* 功能描述: 在打开添加和修改界面时主表及从表数据初始化后再调用此方法
	* 方法的参数和返回值: 
	* @param isNew
	*/
	protected void initOtherData(boolean isNew) {
		
	}

    /**
     * 开发人： andy
     * 开发时间： 2013-9-29 下午01:17:58
     * 功能描述： 初始化打开编辑界面或添加界面时的一些其他数据，如字典表等信息
     * 方法的参数和返回值
     * @throws AppException
     * void 
     * ==================================
     * 修改历史
     * 修改人        修改时间      修改原因及内容
     *
     * ==================================
     */
    protected void initVcId()throws AppException{
   	 	try {
   	 		if(StringUtil.isBlank(po.getVcId())){
   	 			po.setVcId(GeneratorUUID.generateUUID());
   	 		}
			BeanAccessUtil.copyProperty(po, "vcDelFlag", 0);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
    }
    
	public AbstractPO getPo() {
		return po;
	}

	public void setPo(AbstractPO po) {
		this.po = po;
	}
   
}
